/*http server Handler
Created on 2020年05月10日
@author: zxyong 13738196011
 */

package com.zxy.tcp;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Hashtable;

import org.json.JSONObject;

import com.zxy.adminlog.UsAdmin_Log;
import com.zxy.business.Ope_DB_Go;
import com.zxy.business.Query_Data;
import com.zxy.common.Com_Fun;
import com.zxy.common.Com_Para;
import com.zxy.common.EncryptUtil;
import com.zxy.db_Self.DBManager_Self;
import com.zxy.model.Return_Value;

public class ServerHandlerHttp implements Runnable
{
	public static final String	WEB_ROOT	= Com_Para.ApplicationPath + File.separator + "web";
	private Socket				mServSocket;
	private String				strIP		= "0.0.0.0";
	private Return_Value		rv			= new Return_Value();
	private String				is_xml		= "";

	public ServerHandlerHttp(Socket clientSocket) throws InterruptedException
	{
		if(Com_Fun.flagSconnections())
			this.mServSocket = clientSocket;
		else System.out.println("超过系统试用版本时间,请联系开发单位");
		try
		{
			if(DBManager_Self.connectionPool.jdbcDriver.equals("org.sqlite.JDBC"))
				init();
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}

	// web内容加载
	private void webPage_Rel(StringBuilder strUrl,String s_guid,String[] post_str,Query_Data gd,StringBuilder returnMessage,OutputStream output,String web_name_s) throws Exception
	{
		File file = new File(WEB_ROOT + Com_Para.zxyPath + strUrl.toString().substring(0,strUrl.toString().indexOf(web_name_s)) + web_name_s);
		FileInputStream fis = null;
		InputStreamReader is = null;
		BufferedReader br = null;
		if(file.exists())
		{
			try
			{
				output.write(returnMessage.append("\r\n\r\n").toString().getBytes(Com_Para.U_CODE));
				int BUFFER_SIZE = 0;
				fis = new FileInputStream(file);
				byte[] sbytes = new byte[100];
				while((BUFFER_SIZE = fis.read(sbytes)) != -1)
				{
					output.write(sbytes,0,BUFFER_SIZE);
				}
			}
			catch(Exception e)
			{
			}
			finally
			{
				if(fis != null)
					fis.close();
				if(is != null)
					is.close();
				if(br != null)
					br.close();
			}
			output.write("\r\n".getBytes());
			output.flush();
			output.close();
		}
		else
		{
			StringBuilder errorMessage = new StringBuilder("HTTP/1.1 404 File Not Found\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 230\r\n" + "\r\n" + "<h1>未找到正确页面</h1>");
			try
			{
				output.write(errorMessage.toString().getBytes(Com_Para.U_CODE));
				output.write("\r\n".getBytes());
				output.flush();
				output.close();
			}
			catch(IOException e)
			{
			}
		}
	}

	// 发送错误信息
	private StringBuilder Send_Error(StringBuilder strUrl,String s_guid,String[] post_str,Query_Data gd,StringBuilder returnMessage) throws Exception
	{
		// UsAdmin_Log uL = null;
		// try
		// {
		// if((DbConfigSelf.UserDebug.indexOf("|2|") != -1) && (s_guid != ""))
		// {
		// uL = new UsAdmin_Log(Com_Para.ApplicationPath,new
		// StringBuilder("读取数据开始时间跟踪,接收接口请求["
		// + s_guid + "]"));
		// uL.WriteLog();
		// }
		// }
		// catch(IOException ioe2)
		// {
		// }
		returnMessage.delete(0,returnMessage.length());
		returnMessage.append("Error请求语法错误");
		// try
		// {
		// if((DbConfigSelf.UserDebug.indexOf("|2|") != -1) && (s_guid != ""))
		// {
		// uL = new UsAdmin_Log(Com_Para.ApplicationPath,new
		// StringBuilder("读取数据开始时间跟踪,接口数据返回["
		// + s_guid + "]"));
		// uL.WriteLog();
		// }
		// }
		// catch(IOException ioe3)
		// {
		// }
		return returnMessage;
	}

	// 通用接口信息
	private StringBuilder Center_Data_Rel(StringBuilder strUrl,String s_guid,String[] post_str,Query_Data gd,StringBuilder returnMessage,String strIP) throws Exception
	{
		StringBuilder strAry = new StringBuilder();
		Hashtable<String,String> htParam = new Hashtable<String,String>();
		for(String strTemV: strUrl.toString().split("&"))
		{
			String[] strTemPar = strTemV.split("=");
			if(strTemPar.length == 2)
				htParam.put(strTemPar[0],strTemPar[1]);
			else htParam.put(strTemPar[0],"");
		}
		String sub_code = htParam.get("sub_code") == null ? "" : (String)htParam.get("sub_code");
		String sub_usercode = htParam.get("sub_usercode") == null ? "" : (String)htParam.get("sub_usercode");
		String delay_data = htParam.get("delay_data") == null ? "" : (String)htParam.get("delay_data");
		String delay_code = htParam.get("delay_code") == null ? "" : (String)htParam.get("delay_code");
		String param_name = htParam.get("param_name") == null ? "" : (String)htParam.get("param_name");
		String session_id = htParam.get("session_id") == null ? "" : (String)htParam.get("session_id");
		is_xml = htParam.get("is_xml") == null ? "" : (String)htParam.get("is_xml");
		// String s_flag = htParam.get("s_flag") == null ? "0" : (String)
		String jsonpzxyong = htParam.get("jsoncallback") == null ? "" : (String)htParam.get("jsoncallback");
		s_guid = htParam.get("s_guid") == null ? "" : (String)htParam.get("s_guid");
		this.rv.param_name = param_name;
		// 是否需要登录flag
		boolean bFlag = false;
		if((Com_Para.Is_UserLogin != "") && (Com_Para.Is_UserLogin.indexOf("[" + param_name + "]") != -1))
		{
			bFlag = true;
		}
		// 传递in 参数
		ArrayList<String> aryParamValue = new ArrayList<String>();
		for(int i = 1;i < 101;i++)
		{
			boolean tembFlag = false;
			String strVS = "";
			if(htParam.get("param_value" + String.valueOf(i)) != null)
			{
				strVS = (String)htParam.get("param_value" + String.valueOf(i));
				if(i == 1 || i == 2)
					strVS = Com_Fun.getParam_value1(strVS.trim());
				tembFlag = true;
			}
			else
			{
				for(String temstr: post_str)
				{
					if(temstr.indexOf("param_value" + String.valueOf(i) + "=") == 0)
					{
						tembFlag = true;
					}
					else if(temstr.equals("jsonpzxyong"))
						jsonpzxyong = temstr.split("=")[1];
					if((temstr.indexOf("param_value" + String.valueOf(i) + "=") == 0) && (temstr.split("=").length > 1))
					{
						strVS = temstr.split("=")[1];
						if(i == 1 || i == 2)
							strVS = Com_Fun.getParam_value1(strVS);
						break;
					}
				}
			}

			if(!tembFlag)
				break;
			if((bFlag) && (i == 2))
			{
				if(Com_Para.EncryptUtilType == 1)
					strVS = EncryptUtil.getSM32(strVS);
				else strVS = EncryptUtil.getMd5(strVS).toLowerCase();
			}
			aryParamValue.add(i - 1,strVS);
		}
		htParam.clear();
		htParam = null;

		// 用户登录接口
		if(bFlag)
		{
			gd.session_id = Com_Fun.Get_New_GUID();
			strAry = gd.GetDataList(sub_code,sub_usercode,param_name,aryParamValue,strUrl,delay_data,delay_code,strIP);
		}
		// 非登录接口但需要session_id验证
		else if((Com_Para.Login_Session == 1) && (Com_Fun.GetInterSession(param_name)))
		{
			gd.session_id = session_id;
			if(Com_Fun.GetInterSession(param_name))
			{
				if((session_id.equals("")) || (!Com_Fun.HadSession(session_id,session_id)))
				{
					strAry.delete(0,strAry.length());
					strAry.append("{\"" + param_name + "\":[{\"session_id\":\"\",\"s_result\":\"0\",\"error_desc\":\"用户未登陆,请登陆\"}]}");
				}
				else
				{
					strAry = gd.GetDataList(sub_code,sub_usercode,param_name,aryParamValue,strUrl,delay_data,delay_code,strIP);
				}
			}
			else
			{
				strAry = gd.GetDataList(sub_code,sub_usercode,param_name,aryParamValue,strUrl,delay_data,delay_code,strIP);
			}
		}
		// 通用接口
		else
		{
			strAry = gd.GetDataList(sub_code,sub_usercode,param_name,aryParamValue,strUrl,delay_data,delay_code,strIP);
		}

		if(!jsonpzxyong.equals(""))
		{
			strAry.insert(0,jsonpzxyong + "(").append(")");
		}
		if(this.rv.s_result == 1)
			this.rv = gd.rv;
		if(is_xml.equals("1"))
		{
			String temMsg = strAry.toString();
			JSONObject jso = null;
			jso = new JSONObject(temMsg);
			temMsg = Com_Fun.JSONToXml(jso.get(param_name).toString(),param_name);
			strAry.delete(0,strAry.length());
			strAry.append(temMsg);
		}
		// System.gc();
		return strAry;
	}

	// 发送服务端接收请求
	private void Client_Send(StringBuilder strUrl,Socket clientSocket) throws IOException
	{
		if(strUrl.indexOf("@##ST=50") != -1)
		{
			String DEVICE_IP = clientSocket.getInetAddress().getHostAddress();
			String DEVICE_PORT = String.valueOf(clientSocket.getPort());
			Ope_DB_Go odg = new Ope_DB_Go();
			odg.Set_Reg_Device(strUrl,DEVICE_IP,DEVICE_PORT);
		}
	}

	// 线程init
	private void init()
	{
		/* 跟踪当前socket连接数 */
		Com_Para.socket_count++;
		// System.out.println("当前增加线程,总数:"+String.valueOf(Com_Para.socket_count));
		InputStream input = null;
		OutputStream output = null;
		StringBuilder strGS = new StringBuilder("HTTP/1.1 200 OK\r\n" + "Content-Type: text/html\r\n" + "Access-Control-Allow-Methods: POST,GET\r\n" + "Access-Control-Allow-Origin: *\r\n" + "Connection: Keep-Alive");// Keep-Alive
		try
		{
			String s_guid = "";
			strIP = this.mServSocket.getRemoteSocketAddress().toString();
			strIP = strIP.substring(1,strIP.indexOf(":"));
			input = this.mServSocket.getInputStream();
			output = this.mServSocket.getOutputStream();
			Request request = new Request(input);
			request.strIP = strIP;
			request.parse();
			Response response = new Response(output);
			response.setRequest(request);
			StringBuilder strUrl = request.getUri();
			String[] post_str = request.getPost_str();
			/* 判断request是否出现异常 */
			this.rv = request.rv;
			StringBuilder returnMessage = new StringBuilder("HTTP/1.1 200 OK\r\n");
			if(strUrl.indexOf(".html") != -1)
				returnMessage.append("Content-Type: text/html\r\n");
			else if(strUrl.indexOf(".js") != -1)
				returnMessage.append("Content-Type: application/x-javascript\r\n");
			else if(strUrl.indexOf(".css") != -1)
				returnMessage.append("Content-Type: text/css\r\n");
			else if(strUrl.indexOf(".jpg") != -1)
				returnMessage.append("Content-Type: image/jpg\r\n");
			else if(strUrl.indexOf(".gif") != -1)
				returnMessage.append("Content-Type: image/jpg\r\n");
			else if(strUrl.indexOf(".png") != -1)
				returnMessage.append("Content-Type: mage/png\r\n");
			else if(strUrl.indexOf(".svg") != -1)
				returnMessage.append("Content-Type: text/svg+xml\r\n");
			else if(strUrl.indexOf(".eot") != -1)
				returnMessage.append("Content-Type: application/vnd.ms-fontobject\r\n");
			else if(strUrl.indexOf(".ttf") != -1)
				returnMessage.append("Content-Type: application/x-font-ttf\r\n");
			else if(strUrl.indexOf(".woff") != -1)
				returnMessage.append("Content-Type: application/x-font-woff\r\n");
			else if(strUrl.indexOf(".woff2") != -1)
				returnMessage.append("Content-Type: application/x-font-woff\r\n");
			else if(strUrl.indexOf(".ico") != -1)
				returnMessage.append("Content-Type: image/ico\r\n");
			else returnMessage.append("Content-Type: text/html\r\n");
			returnMessage.append("Access-Control-Allow-Methods: POST,GET\r\n" + "Access-Control-Allow-Origin:*" + Com_Para.HttpUrl + "\r\n" + "Connection: Keep-Alive");
			StringBuilder strResult = new StringBuilder("-1");
			Query_Data gd = new Query_Data(this.rv);
			// System.out.println("当前url:" + strUrl);
			// 通用接口
			if(strUrl.indexOf(Com_Para.web_Name[0]) != -1)
			{
				webPage_Rel(strUrl,s_guid,post_str,gd,returnMessage,output,Com_Para.web_Name[0]);
			}
			else if(strUrl.indexOf(Com_Para.web_Name[1]) != -1)
			{
				webPage_Rel(strUrl,s_guid,post_str,gd,returnMessage,output,Com_Para.web_Name[1]);
			}
			else if(strUrl.indexOf(Com_Para.web_Name[2]) != -1)
			{
				webPage_Rel(strUrl,s_guid,post_str,gd,returnMessage,output,Com_Para.web_Name[2]);
			}
			else if(strUrl.indexOf(Com_Para.web_Name[3]) != -1)
			{
				webPage_Rel(strUrl,s_guid,post_str,gd,returnMessage,output,Com_Para.web_Name[3]);
			}
			else if(strUrl.indexOf(Com_Para.web_Name[4]) != -1)
			{
				webPage_Rel(strUrl,s_guid,post_str,gd,returnMessage,output,Com_Para.web_Name[4]);
			}
			else if(strUrl.indexOf(Com_Para.web_Name[5]) != -1)
			{
				webPage_Rel(strUrl,s_guid,post_str,gd,returnMessage,output,Com_Para.web_Name[5]);
			}
			else if(strUrl.indexOf(Com_Para.web_Name[6]) != -1)
			{
				webPage_Rel(strUrl,s_guid,post_str,gd,returnMessage,output,Com_Para.web_Name[6]);
			}
			else if(strUrl.indexOf(Com_Para.web_Name[7]) != -1)
			{
				webPage_Rel(strUrl,s_guid,post_str,gd,returnMessage,output,Com_Para.web_Name[7]);
			}
			else if(strUrl.indexOf(Com_Para.web_Name[8]) != -1)
			{
				webPage_Rel(strUrl,s_guid,post_str,gd,returnMessage,output,Com_Para.web_Name[8]);
			}
			else if(strUrl.indexOf(Com_Para.web_Name[9]) != -1)
			{
				webPage_Rel(strUrl,s_guid,post_str,gd,returnMessage,output,Com_Para.web_Name[9]);
			}
			else if(strUrl.indexOf(Com_Para.web_Name[10]) != -1)
			{
				webPage_Rel(strUrl,s_guid,post_str,gd,returnMessage,output,Com_Para.web_Name[10]);
			}
			else if(strUrl.indexOf(Com_Para.web_Name[11]) != -1)
			{
				webPage_Rel(strUrl,s_guid,post_str,gd,returnMessage,output,Com_Para.web_Name[11]);
			}
			// 通用数据接口
			else if((strUrl.indexOf("sub_code=") != -1) && (strUrl.indexOf("param_name=") != -1))
			{
				strResult.delete(0,strResult.length());
				strResult = Center_Data_Rel(strUrl,s_guid,post_str,gd,returnMessage,strIP);
			}
			// 其他信息
			else if((!strUrl.toString().trim().equals("")) && (strUrl.toString().trim().indexOf("GET /favicon.ico HTTP/1.1") != -1))
			{
				strResult.delete(0,strResult.length());
				strResult = Send_Error(strUrl,s_guid,post_str,gd,returnMessage);
			}

			if(!strResult.toString().equals("-1"))
			{
				output.write((returnMessage.toString() + "\r\n\r\n" + strResult.toString() + "\r\n").getBytes(Com_Para.U_CODE));
				output.flush();
				output.close();
			}
			// 发送统一服务内容
			Client_Send(strUrl,this.mServSocket);
		}
		catch(Exception e)
		{
			UsAdmin_Log uL = new UsAdmin_Log(Com_Para.ApplicationPath,new StringBuilder("接收到错误请求[ServerHandlerHttp]\r\n" + e.getMessage()));
			try
			{
				uL.WriteLog();
			}
			catch(IOException localIOException4)
			{
			}
			try
			{
				output.write(strGS.append("\r\n\r\n").append(e.getMessage()).append("\r\n").toString().getBytes(Com_Para.U_CODE));
			}
			catch(IOException e1)
			{
			}
		}
		finally
		{
			try
			{
				if(input != null)
					input.close();
				if(output != null)
					output.close();

				if(this.mServSocket != null)
				{
					Com_Para.socket_count--;
				}
			}
			catch(Exception ees)
			{
			}
		}
	}

	public void run()
	{
		try
		{
			if(!DBManager_Self.connectionPool.jdbcDriver.equals("org.sqlite.JDBC"))
				init();
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
}